<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>java的hashcode</title>
    <style>
        body {
            background-color: #c7edcc
        }
    </style>
</head>
<body>
<pre>

     一:String的hashcode实现:

     //s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

    对于字符串"abc",可以这么计算哈希hashcode=(int)a+(int)b+(int)c;但是这种方法abc,cba和acb等值一样,哈希冲突概率很大,所以String加入了个位置信息,

    改成这样hashcode=(int)a*31^(n-1)+(int)b*31^(n-2)+(int)c*31^(n-3)+...

    这里为什么使用了31,《Effective Java》是这样说的：之所以选择31，是因为它是个奇素数，如果乘数是偶数，并且乘法溢出的话，信息就会丢失，因为与2相乘等价于移位运算。
    使用素数的好处并不是很明显，但是习惯上都使用素数来计算散列结果。31有个很好的特性，就是用移位和减法来代替乘法，可以得到更好的性能：31*i==(i<<5)-i。现在的VM可以自动完成这种优化。

    简单来说:
    1.使用偶数会导致乘法溢出数据丢失,因为很多大的数据信息都丢失了,加大哈希冲突概率
    2.31*i==(i<<5)-i。现在的VM可以自动完成这种优化,移位加减法比乘法除法开销更小


    二:HashMap的hashcode实现:




</pre>
</body>
</html>